package main;

import java.io.*;
import java.io.FileReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class AESTest {   
    private static final String ALGORITHM = "AES";  
      
    /** 
     * 生成密钥 
     * @return 
     * @throws Exception 
     */  
    public SecretKey geneKey() throws Exception {  
        //获取一个密钥生成器实例  
        KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);  
        SecureRandom random = new SecureRandom();  
        random.setSeed("123456".getBytes());//设置加密用的种子，密钥  
        keyGenerator.init(random);  
        SecretKey secretKey = keyGenerator.generateKey();  
        //把上面的密钥存起来  
        Path keyPath = Paths.get("C:\\Users\\Administrator\\git\\lsp\\lsp\\miyao\\aes.key"); 
        Files.write(keyPath, secretKey.getEncoded());  
        return secretKey;  
    }  
      
    /** 
     * 读取存储的密钥 
     * @param keyPath 
     * @return 
     * @throws Exception 
     */  
    public SecretKey readKey(Path keyPath) throws Exception {  
        //读取存起来的密钥  
        byte[] keyBytes = Files.readAllBytes(keyPath);  
        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, ALGORITHM);  
        return keySpec;  
    }  
    
    public static int  main1(List<Integer> v,int s) throws Exception {
    	 Cipher cipher = Cipher.getInstance(ALGORITHM);//算法是AES  
         //2、生成/读取用于加解密的密钥  
    	 AESTest aes = new AESTest();
         SecretKey secretKey = aes.geneKey();  
         //3、用指定的密钥初始化Cipher对象，指定是加密模式，还是解密模式  
         cipher.init(Cipher.ENCRYPT_MODE, secretKey);  
         String content = "Hello AES";//需要加密的内容  
         MakeFile.main2();
         String pathname = "D:\\test.txt"; // 绝对路径或相对路径都可以，这里是绝对路径，写入文件时演示相对路径  
         File filename = new File(pathname); // 要读取以上路径的input。txt文件  
         InputStreamReader reader = new InputStreamReader(  
                 new FileInputStream(filename)); // 建立一个输入流对象reader  
         BufferedReader br = new BufferedReader(reader); // 建立一个对象，它把文件内容转成计算机能读懂的语言  
         String line = "";  
         line = br.readLine();  
         while (line != null) {  
             line = br.readLine(); // 一次读入一行数据  
             
             System.out.println(line);
             content = content+line;
         } 
         
//         System.out.println("content"content);
         //4、更新需要加密的内容  
         cipher.update(content.getBytes());  
         //5、进行最终的加解密操作  
         byte[] result = cipher.doFinal();//加密后的字节数组  
         
         
         int a =  byteArrayToInt(result);
        
         
         return a%s;
//         System.out.println(a%s);
//         //也可以把4、5步组合到一起，但是如果保留了4步，同时又是如下这样使用的话，加密的内容将是之前update传递的内容和doFinal传递的内容的和。  
////       byte[] result = cipher.doFinal(content.getBytes()); 
//         
//         
////         String base64Result = Base64.getEncoder().encodeToString(result);//对加密后的字节数组进行Base64编码  
//         System.out.println("Result: " + base64Result); 
//         
//         
//         Cipher cipher2 = Cipher.getInstance(ALGORITHM);  
//         SecretKey secretKey2 = aes.geneKey();  
//         cipher2.init(Cipher.DECRYPT_MODE, secretKey2);
//         content = base64Result;//经过Base64加密的待解密的内容  
//         byte[] encodedBytes = Base64.getDecoder().decode(content.getBytes());  
//         result = cipher.doFinal(encodedBytes);//对加密后的字节数组进行解密  
//         System.out.println("Result: " + new String(result)); 
	}
    public static void main(String[] args) throws Exception {
    	
    	List<Integer> v = new ArrayList<>();
		int i = main1(v, 10);
		System.out.println(i);
	}
    
    public static int byteArrayToInt(byte[] b) {   
    	return   b[3] & 0xFF |   
    	            (b[2] & 0xFF) << 8 |   
    	            (b[1] & 0xFF) << 16 |   
    	            (b[0] & 0xFF) << 24;   
    	}   
    	public static byte[] intToByteArray(int a) {   
    	return new byte[] {   
    	        (byte) ((a >> 24) & 0xFF),   
    	        (byte) ((a >> 16) & 0xFF),      
    	        (byte) ((a >> 8) & 0xFF),      
    	        (byte) (a & 0xFF)   
    	    };   
    	} 
      
    /** 
     * 加密测试 
     */  
//    @Test  
    public void testEncrypt() throws Exception {  
        //1、指定算法、获取Cipher对象  
        Cipher cipher = Cipher.getInstance(ALGORITHM);//算法是AES  
        //2、生成/读取用于加解密的密钥  
        SecretKey secretKey = this.geneKey();  
        //3、用指定的密钥初始化Cipher对象，指定是加密模式，还是解密模式  
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);  
        String content = "Hello AES";//需要加密的内容  
        //4、更新需要加密的内容  
        cipher.update(content.getBytes());  
        //5、进行最终的加解密操作  
        byte[] result = cipher.doFinal();//加密后的字节数组  
        //也可以把4、5步组合到一起，但是如果保留了4步，同时又是如下这样使用的话，加密的内容将是之前update传递的内容和doFinal传递的内容的和。  
//      byte[] result = cipher.doFinal(content.getBytes());  
        String base64Result = Base64.getEncoder().encodeToString(result);//对加密后的字节数组进行Base64编码  
        System.out.println("Result: " + base64Result); 
        
        content = base64Result;//经过Base64加密的待解密的内容  
        byte[] encodedBytes = Base64.getDecoder().decode(content.getBytes());  
        result = cipher.doFinal(encodedBytes);//对加密后的字节数组进行解密  
        System.out.println("Result: " + new String(result)); 
        
    }  
      
    /** 
     * 解密测试 
     */  
//    @Test  
    public void testDecrpyt() throws Exception {  
        Cipher cipher = Cipher.getInstance(ALGORITHM);  
        SecretKey secretKey = this.geneKey();  
        cipher.init(Cipher.DECRYPT_MODE, secretKey);  
        String content = "pK9Xw4zqTMXYraDadSGJE3x/ftrDxIg2AM/acq0uixA=";//经过Base64加密的待解密的内容  
        System.out.println("Result: " + new String(result));  
    }  
      
} 
